import requests
import hmac
import hashlib
import base64
import json
import time
from datetime import datetime
from urllib.parse import urlencode
from typing import Dict, Optional, List

class BrokerAPI:
    def __init__(self, 
                 api_key: str, 
                 secret_key: str, 
                 account_id: str,
                 base_url: str = "https://api.example.com/v1"):
        """
        初始化券商API接口
        
        参数:
            api_key: API密钥
            secret_key: 密钥
            account_id: 资金账户ID
            base_url: API基础URL
        """
        self.api_key = api_key
        self.secret_key = secret_key
        self.account_id = account_id
        self.base_url = base_url
        self.session = requests.Session()
        
        # 设置通用请求头
        self.session.headers.update({
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'X-API-KEY': self.api_key
        })

    def _generate_signature(self, 
                          method: str, 
                          endpoint: str, 
                          params: Dict = {}) -> tuple:
        """生成API签名"""
        timestamp = str(int(time.time() * 1000))
        
        # 构建签名字符串
        sign_str = timestamp + method.upper() + endpoint
        if params:
            sign_str += json.dumps(params, sort_keys=True)
            
        # 使用HMAC-SHA256生成签名
        signature = hmac.new(
            self.secret_key.encode('utf-8'),
            sign_str.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        
        return signature, timestamp

    def _request(self, 
                 method: str, 
                 endpoint: str, 
                 params: Dict = {}) -> Dict:
        """发送API请求"""
        try:
            # 生成签名
            signature, timestamp = self._generate_signature(method, endpoint, params)
            
            # 更新请求头
            headers = {
                'X-TIMESTAMP': timestamp,
                'X-SIGNATURE': signature
            }
            
            url = f"{self.base_url}{endpoint}"
            
            # 发送请求
            if method.upper() == 'GET':
                if params:
                    url += '?' + urlencode(params)
                response = self.session.get(url, headers=headers)
            else:
                response = self.session.request(
                    method=method,
                    url=url,
                    headers=headers,
                    json=params
                )
            
            # 检查响应状态
            response.raise_for_status()
            
            return response.json()
            
        except requests.exceptions.RequestException as e:
            raise Exception(f"API请求错误: {str(e)}")

    def get_account_info(self) -> Dict:
        """获取账户信息"""
        endpoint = f"/accounts/{self.account_id}"
        return self._request('GET', endpoint)

    def get_positions(self) -> List[Dict]:
        """获取当前持仓"""
        endpoint = f"/accounts/{self.account_id}/positions"
        response = self._request('GET', endpoint)
        return response.get('positions', [])

    def get_market_data(self, symbol: str) -> Optional[Dict]:
        """获取市场行情数据"""
        endpoint = "/market/snapshot"
        params = {'symbol': symbol}
        try:
            response = self._request('GET', endpoint, params)
            return response.get('data')
        except Exception as e:
            print(f"获取行情数据失败: {str(e)}")
            return None

    def get_latest_price(self, symbol: str) -> Optional[float]:
        """获取最新价格"""
        market_data = self.get_market_data(symbol)
        if market_data:
            return market_data.get('last_price')
        return None

    def place_order(self, 
                   symbol: str, 
                   direction: str, 
                   volume: int, 
                   price: float = 0.0) -> Dict:
        """
        下单
        
        参数:
            symbol: 交易标的代码
            direction: 交易方向 ("BUY" or "SELL")
            volume: 交易数量
            price: 委托价格（None表示市价单）
        """
        endpoint = f"/accounts/{self.account_id}/orders"
        
        params = {
            'symbol': symbol,
            'direction': direction,
            'volume': volume,
            'order_type': 'MARKET' if price is None else 'LIMIT',
        }
        
        if price is not None:
            params['price'] = price
            
        try:
            response = self._request('POST', endpoint, params)
            return {
                'status': 'SUCCESS',
                'order_id': response.get('order_id'),
                'message': '下单成功'
            }
        except Exception as e:
            return {
                'status': 'FAILED',
                'message': str(e)
            }

    def cancel_order(self, order_id: str) -> Dict:
        """撤单"""
        endpoint = f"/accounts/{self.account_id}/orders/{order_id}"
        try:
            response = self._request('DELETE', endpoint)
            return {
                'status': 'SUCCESS',
                'message': '撤单成功'
            }
        except Exception as e:
            return {
                'status': 'FAILED',
                'message': str(e)
            }

    def get_order_status(self, order_id: str) -> Dict:
        """查询订单状态"""
        endpoint = f"/accounts/{self.account_id}/orders/{order_id}"
        return self._request('GET', endpoint)

    def get_trade_history(self, 
                         start_time: str = "", 
                         end_time: str = "") -> List[Dict]:
        """获取交易历史"""
        endpoint = f"/accounts/{self.account_id}/trades"
        params = {}
        if start_time:
            params['start_time'] = start_time
        if end_time:
            params['end_time'] = end_time
            
        response = self._request('GET', endpoint, params)
        return response.get('trades', [])

    def get_account_balance(self) -> Dict:
        """获取账户资金情况"""
        endpoint = f"/accounts/{self.account_id}/balance"
        return self._request('GET', endpoint)
